﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Domain;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Media;
using Nop.Core.Domain.ShareBuy;
using Nop.Services.Customers;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Media;
using Nop.Services.Messages;
using Nop.Services.ShareBuy;
using Nop.Services.Catalog;
using Nop.Web.Models.ShareBuy;
using Nop.Web.Extensions;
using Nop.Services.Logging;
using Newtonsoft.Json;
using Nop.Web.Models.Media;
using Nop.Services.Orders;
using Nop.Services.Configuration;
using Nop.Web.Infrastructure.Cache;
using Nop.Core.Domain.Catalog;
using Nop.Core.Caching;
using Nop.Services.Security;
using Nop.Services.Stores;
using Nop.Web.Models.Catalog;
using Nop.Services.Seo;

namespace Nop.Web.Controllers
{
    public class ShareBuyController : BaseNopController
    {
        #region Fields

        private readonly IShareBuyService _shareBuyService;
        private readonly IWorkContext _workContext;
        private readonly IPictureService _pictureService;
        private readonly ILocalizationService _localizationService;
        private readonly IDateTimeHelper _dateTimeHelper;
        private readonly IWorkflowMessageService _workflowMessageService;
        private readonly IWebHelper _webHelper;
        private readonly IProductService _productService;

        private readonly MediaSettings _mediaSettings;
        private readonly LocalizationSettings _localizationSettings;
        private readonly CustomerSettings _customerSettings;
        private readonly StoreInformationSettings _storeInformationSettings;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly RewardPointsSettings _rewardPointsSettings;
        private readonly ICustomerService _customerService;
        private readonly IOrderService _orderService;
        private readonly ICategoryService _categoryService;
        private readonly ISettingService _settingService;
        private readonly ShareBuySettings _sharebuySettings;
        private readonly ICacheManager _cacheManager;

        #endregion

        #region Constructors

        public ShareBuyController(IShareBuyService shareBuyService,
            IWorkContext workContext, IPictureService pictureService, ILocalizationService localizationService,
            IDateTimeHelper dateTimeHelper,
            IWorkflowMessageService workflowMessageService, IWebHelper webHelper,
            MediaSettings mediaSettings,
            LocalizationSettings localizationSettings, CustomerSettings customerSettings,
            StoreInformationSettings storeInformationSettings, IProductService productSerivce, ICustomerActivityService customerActivityService,
            RewardPointsSettings rewardPointsSettings, ICustomerService customerService,
            IOrderService orderService,ICategoryService categoryService,
            ISettingService settingService,ShareBuySettings shareBuySettings,
            ICacheManager cacheManager)
        {
            this._shareBuyService = shareBuyService;
            this._workContext = workContext;
            this._pictureService = pictureService;
            this._localizationService = localizationService;
            this._dateTimeHelper = dateTimeHelper;
            this._workflowMessageService = workflowMessageService;
            this._webHelper = webHelper;

            this._mediaSettings = mediaSettings;
            this._localizationSettings = localizationSettings;
            this._customerSettings = customerSettings;
            this._storeInformationSettings = storeInformationSettings;
            this._productService = productSerivce;
            this._customerActivityService = customerActivityService;
            this._rewardPointsSettings = rewardPointsSettings;
            this._customerService = customerService;
            this._orderService = orderService;
            this._categoryService = categoryService;
            this._settingService = settingService;
            this._sharebuySettings = shareBuySettings;
            this._cacheManager = cacheManager;
        }

        #endregion

        #region Utilities

        #endregion

        #region Methods
        //create shareBuy 
        public ActionResult Create(int orderId, int productId)
        {
            var model = new ShareBuyModel();
            bool canShare = _shareBuyService.CanCreateShareBuy(_workContext.CurrentCustomer.Id, orderId, productId);
            if (canShare)
            {
                int parentCategoryId = _sharebuySettings.RootCategoryId;
                var shareCategories = _categoryService.GetAllCategoriesByParentCategoryId(parentCategoryId);
                if (shareCategories != null && shareCategories.Count > 0)
                {
                    foreach (var item in shareCategories)
                    {
                        model.CategorySelectList.Add(new SelectListItem() { Text = item.Name, Value = item.Id.ToString() });
                    }
                }
                if (model.CategorySelectList.Count == 0)
                {
                    model.CategorySelectList.Add(new SelectListItem() { Text = "No category,please refresh", Value = "" });
                }
                var productVariants = _shareBuyService.GetCanShareOrderItems(orderId);//_orderService.GetAllOrderProductVariants(orderId, null, null, null, null, null, null);
                if (productVariants != null && productVariants.Count > 0)
                {
                    foreach (var item in productVariants)
                    {
                        model.ProductVariantSelectList.Add(new SelectListItem() { Text = item.Product.Name, Value = item.ProductId.ToString(), Selected = productId > 0 && productId == item.ProductId });
                    }
                }
                if (model.ProductVariantSelectList.Count == 0)
                {
                    model.ProductVariantSelectList.Add(new SelectListItem() { Text="No product,please refresh",Value=""});
                }
                var product = _productService.GetProductById(productId);
                if (product != null)
                {
                    model.ProductName = product.Name;
                }
                model.ProductId = productId;
                model.CustomerId = _workContext.CurrentCustomer.Id;
                model.OrderId = orderId;
            }
            else
            {
                model.ProductName = "Can not create sharing,please retry.";
            }
            return View(model);

        }
        [HttpPost]
        public ActionResult Save(int id,int categoryId,int orderId, int productId, int cutomerId, string title, string description, string picturesJSON, int defaultPictureId)
        {
            //shareBuyPictures
            List<ShareBuyPicture> shareBuyPictures = new List<ShareBuyPicture>();
            shareBuyPictures = JsonConvert.DeserializeObject<List<ShareBuyPicture>>(picturesJSON);
            List<ShareBuyCategory> shareBuyCategories = new List<ShareBuyCategory>();
            ShareBuyCategory shareBuyCategory = new ShareBuyCategory();
            shareBuyCategory.CategoryId = categoryId;
            shareBuyCategories.Add(shareBuyCategory);

            //is the costume category? 
            bool isCostumeCategory = false;
            var product = _productService.GetProductById(productId);
            var productCategories=product.ProductCategories;
            foreach (var item in productCategories)
            {
                if (item.Category.Name == _sharebuySettings.CostumeCategroyName.Trim())
                {
                    isCostumeCategory = true;
                }
            }

            //add
            if (id <= 0)
            {
                //sharebuy
                var sharebuy = new ShareBuyItem();
                sharebuy.Id = id;
                sharebuy.CustomerId = cutomerId;
                sharebuy.DefaultPictureId = defaultPictureId;
                sharebuy.Description = description;
                sharebuy.OrderId = orderId;
                sharebuy.ProductId = productId;
                sharebuy.Title = title;
                sharebuy.CreatedOnUtc = DateTime.UtcNow;
                sharebuy.UpdatedOnUtc = DateTime.UtcNow;
                sharebuy.ShareBuyPictures = shareBuyPictures;
                sharebuy.ShareBuyCategories = shareBuyCategories;
                _shareBuyService.InsertShareBuy(sharebuy);

                //add reward points
                if (_rewardPointsSettings.Enabled &&
                _rewardPointsSettings.PointsForAddShareBuy > 0)
                    _workContext.CurrentCustomer.AddRewardPointsHistoryEntry(isCostumeCategory?_rewardPointsSettings.PointsForAddCostumeShareBuy:_rewardPointsSettings.PointsForAddShareBuy, "Make a new buying sharing");
                _customerService.UpdateCustomer(_workContext.CurrentCustomer);

                //activity log
                _customerActivityService.InsertActivity("AddNewShareBuy", _localizationService.GetResource("ActivityLog.AddNewShareBuy"), sharebuy.Title);
                SuccessNotification(_localizationService.GetResource("ShareBuy.Added"));
                return Json(new { Result = true, Id = sharebuy.Id }, JsonRequestBehavior.AllowGet);
            }
            else //edit
            {
                var sharebuy = _shareBuyService.GetShareBuyById(id);
                sharebuy.DefaultPictureId = defaultPictureId;
                sharebuy.Description = description;
                sharebuy.Title = title;
                sharebuy.UpdatedOnUtc = DateTime.UtcNow;

                //share buy pictures
                foreach (var item_new in shareBuyPictures)
                {
                    bool isNew = true;
                    foreach (var item in sharebuy.ShareBuyPictures)
                    {
                        if (item.PictureId == item_new.PictureId)
                        {
                            item.DisplayOrder = item_new.DisplayOrder;
                            isNew = false;
                        }
                    }
                    if (isNew)
                    {
                        sharebuy.ShareBuyPictures.Add(new ShareBuyPicture
                        {
                            DisplayOrder = item_new.DisplayOrder,
                            PictureId = item_new.PictureId,
                            ShareBuyItemId = item_new.ShareBuyItemId
                        }
                        );
                    }
                }

                _shareBuyService.UpdateShareBuy(sharebuy);
                //activity log
                _customerActivityService.InsertActivity("editNewShareBuy", _localizationService.GetResource("ActivityLog.EditNewShareBuy"), sharebuy.Title);
                SuccessNotification(_localizationService.GetResource("ShareBuy.Edited"));
                return Json(new { Result = true, Id = sharebuy.Id }, JsonRequestBehavior.AllowGet);
            }

        }

        public ActionResult Edit(int id)
        {
            var shareBuyItem = _shareBuyService.GetShareBuyById(id);
            if (shareBuyItem == null)
                //No shareBuyItem item found with the specified id
                return RedirectToAction("List");

            var model = shareBuyItem.ToModel();

            PrepareShareBuyDefaultPictureModel(model);
            PrepareShareBuyPictureModels(model);

            return View(model);
        }

        public ActionResult Detail(int id)
        {
            var shareBuyItem = _shareBuyService.GetShareBuyById(id);
            if (shareBuyItem == null)
                //No shareBuyItem item found with the specified id
                return RedirectToAction("List");

            var model = shareBuyItem.ToModel();

            //prepare customer model
            string avatarUrl = "待修改";//_pictureService.GetPictureUrl(shareBuyItem.Customer.GetAttribute<int>(SystemCustomerAttributeNames.AvatarPictureId), _mediaSettings.AvatarPictureSize, false);
            if (String.IsNullOrEmpty(avatarUrl) && _customerSettings.DefaultAvatarEnabled)
                avatarUrl = _pictureService.GetDefaultPictureUrl(_mediaSettings.AvatarPictureSize, PictureType.Avatar);
            model.CustomerAvatarUrl = avatarUrl;
            model.CustomerName = shareBuyItem.Customer.Email;

            //prepare comments
            var shareItemComments = shareBuyItem.ShareBuyComments.OrderBy(pr => pr.CreatedOnUtc);
            foreach (var nc in shareItemComments)
            {
                var commentModel = new ShareBuyCommentModel()
                {
                    Id = nc.Id,
                    CustomerId = nc.CustomerId,
                    CustomerName = nc.Customer.FormatUserName(),
                    CommentText = nc.CommentText,
                    CreatedOn = _dateTimeHelper.ConvertToUserTime(nc.CreatedOnUtc, DateTimeKind.Utc)

                };

                var customer = nc.Customer;
                string customerAvatarUrl = "待修改";//_pictureService.GetPictureUrl(customer.GetAttribute<int>(SystemCustomerAttributeNames.AvatarPictureId), _mediaSettings.AvatarPictureSize, false);
                if (String.IsNullOrEmpty(customerAvatarUrl) && _customerSettings.DefaultAvatarEnabled)
                    customerAvatarUrl = _pictureService.GetDefaultPictureUrl(_mediaSettings.AvatarPictureSize, PictureType.Avatar);
                commentModel.CustomerAvatarUrl = customerAvatarUrl;

                model.ShareBuyCommentModels.Add(commentModel);
            }

            //product variant pictures
            var pictures = _pictureService.GetPicturesByProductId(shareBuyItem.Product.Id);
            if (pictures.Count > 0)
            {
                model.ProductDetailsModel.DefaultPictureModel = new PictureModel
                {
                    ImageUrl = _pictureService.GetPictureUrl(pictures.FirstOrDefault(), _mediaSettings.ProductThumbPictureSize),
                    FullSizeImageUrl = _pictureService.GetPictureUrl(pictures.FirstOrDefault()),
                    //ImageUrlSize300 = _pictureService.GetPictureUrl(pictures.FirstOrDefault(), 300),
                    Title = string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.ProductName),
                    AlternateText = string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.ProductName),
                };
            }
            else
            {
                //no images. set the default one
                model.ProductDetailsModel.DefaultPictureModel = new PictureModel()
                {
                    ImageUrl = _pictureService.GetDefaultPictureUrl(_mediaSettings.ProductThumbPictureSize),
                    FullSizeImageUrl = _pictureService.GetDefaultPictureUrl(),
                    Title = string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.ProductName),
                    AlternateText = string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.ProductName),
                };
            }

            PrepareShareBuyDefaultPictureModel(model);
            PrepareShareBuyPictureModels(model);

            return View(model);
        }

        [HttpPost]
        public ActionResult Detail(ShareBuyModel shareBuyModel)
        {
            var shareItem = _shareBuyService.GetShareBuyById(shareBuyModel.Id);
            if (shareItem == null )
                return RedirectToRoute("HomePage");

            //add sharebuy comment
            var shareBuyComment = new ShareBuyComment
            {
                Id = 0,
                ShareBuyItemId = shareBuyModel.Id,
                CommentText = shareBuyModel.AddShareBuyCommentModel.CommentText,
                CustomerId = _workContext.CurrentCustomer.Id,
                CreatedOnUtc = DateTime.UtcNow
            };
            shareItem.ShareBuyComments.Add(shareBuyComment);
            _shareBuyService.UpdateShareBuy(shareItem);

            //add reward points
            if (_rewardPointsSettings.Enabled &&
            _rewardPointsSettings.PointsForAddShareBuyComment > 0)
                _workContext.CurrentCustomer.AddRewardPointsHistoryEntry(_rewardPointsSettings.PointsForAddShareBuyComment, "Added a new sharebuy comment");
            _customerService.UpdateCustomer(_workContext.CurrentCustomer);

            //activity log
            _customerActivityService.InsertActivity("comment shareBuy", "ActivityLog.CommentShareBuy");
            SuccessNotification("Commented");

            return RedirectToRoute("ShareBuyDetail", new { id = shareBuyModel.Id });
        }

        public ActionResult List(int categoryId, ShareBuyPagingFilteringModel command)
        {
            var model = new ShareBuyItemListModel();

            if (command.PageSize <= 0) command.PageSize = 10;
            if (command.PageNumber <= 0) command.PageNumber = 1;
            string keyword = "";
            if (Request.Params["Q"] != null)
            {
                keyword = Server.UrlDecode(Request.Params["Q"].ToString());
                model.Q = keyword;
            }
            bool showHidden = true;
            var shareBuyItems = _shareBuyService.GetShareBuys(categoryId,keyword, command.PageNumber - 1, command.PageSize, showHidden);

            model.PagingFilteringContext.LoadPagedList(shareBuyItems);

            model.ShareBuyItems = shareBuyItems
                .Select(x =>
                {
                    var shareBuyModel = new ShareBuyItemModel();
                    PrepareShareBuyItemModel(shareBuyModel, x, true);
                    return shareBuyModel;
                })
                .ToList();

            return View(model);
        }

        public ActionResult HotList(ShareBuyPagingFilteringModel command)
        {
            var model = new ShareBuyItemListModel();

            if (command.PageSize <= 0) command.PageSize = 9;
            if (command.PageNumber <= 0) command.PageNumber = 1;
            bool showHidden = true;
            var shareBuyItems = _shareBuyService.GetHotShareBuys(command.PageNumber - 1, command.PageSize, showHidden);

            model.PagingFilteringContext.LoadPagedList(shareBuyItems);

            model.ShareBuyItems = shareBuyItems
                .Select(x =>
                {
                    var shareBuyModel = new ShareBuyItemModel();
                    PrepareShareBuyItemModel(shareBuyModel, x, true);
                    return shareBuyModel;
                })
                .ToList();

            return View(model);
        }

        [HttpPost]
        public ActionResult ShareBuyPictureDelete(int id)
        {
            var shareBuyPicture = _shareBuyService.GetShareBuyPictureById(id);
            if (shareBuyPicture == null)
                throw new ArgumentException("No shareBuy picture found with the specified id");

            _shareBuyService.DeleteShareBuyPicture(shareBuyPicture);

            var picture = _pictureService.GetPictureById(shareBuyPicture.PictureId);
            _pictureService.DeletePicture(picture);

            return Json(new { Result = true }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult AddVote(int shareBuyItemId)
        {
            ShareBuyVote shareBuyVote = new ShareBuyVote
            {
                CustomerId = _workContext.CurrentCustomer.Id,
                ShareBuyItemId = shareBuyItemId
            };
            if (_shareBuyService.CheckShareBuyVoteExists(shareBuyVote))
            {
                return Json(new { Result = "Exists" }, JsonRequestBehavior.AllowGet);
            }
            _shareBuyService.InsertShareBuyVote(shareBuyVote);
            return Json(new { Result = true }, JsonRequestBehavior.AllowGet);
        }

        [ChildActionOnly]
        //[OutputCache(Duration = 120, VaryByCustom = "WorkingLanguage")]
        public ActionResult ShareCategoryNavigation(int currentCategoryId)
        {
            string cacheKey = string.Format(ModelCacheEventConsumerExtend.SHAREBUY_CATEGORY_NAVIGATION_MODEL_KEY, currentCategoryId, _workContext.WorkingLanguage.Id);
            var cacheModel = _cacheManager.Get(cacheKey, () =>
            {
                var breadCrumb = _categoryService.GetAllCategoriesByParentCategoryId(currentCategoryId);
                var model = PrepareCategoryNavigationModel(breadCrumb);
                return model;
            });
            return PartialView(cacheModel);
        }

        #endregion

        #region Utilities
        [NonAction]
        protected void PrepareShareBuyItemModel(ShareBuyItemModel model, ShareBuyItem shareBuyItem, bool prepareComments)
        {
            if (shareBuyItem == null)
                throw new ArgumentNullException("shareBuyItem");

            if (model == null)
                throw new ArgumentNullException("model");

            model.Id = shareBuyItem.Id;
            model.CreatedOnUtc = shareBuyItem.CreatedOnUtc;
            model.Title = shareBuyItem.Title;
            model.Description = shareBuyItem.Description;
            model.Likes = shareBuyItem.ShareBuyVotes.Count;
            model.NumberOfComments = shareBuyItem.ShareBuyComments.Count;
            model.UpdatedOnUtc = shareBuyItem.UpdatedOnUtc;
            //shareBuy pictures
            int height = 0;
            string pictureUrl = _pictureService.GetPictureUrl(shareBuyItem.DefaultPictureId, 220);//待修改，返回Height
            model.DefaultPictureModel = new ShareBuyPictureModel
            {
                Default = true,
                DisplayOrder = 0,
                PictureId = shareBuyItem.DefaultPictureId,
                ShareBuyId = shareBuyItem.Id,
                PictureUrl = pictureUrl,
                Height=height
            };

            //shareBuy votes
            model.Likes = shareBuyItem.ShareBuyVotes.Count;
            //shareBuy commments
            if (prepareComments)
            {
                PrepareShareBuyComments(model, shareBuyItem);
            }
        }

        [NonAction]
        private void PrepareShareBuyComments(ShareBuyItemModel model, ShareBuyItem shareBuyItem)
        {
            var shareItemComments = shareBuyItem.ShareBuyComments.OrderBy(pr => pr.CreatedOnUtc);
            foreach (var nc in shareItemComments)
            {
                var commentModel = new ShareBuyCommentModel()
                {
                    Id = nc.Id,
                    CustomerId = nc.CustomerId,
                    CustomerName = nc.Customer.FormatUserName(),
                    CommentText = nc.CommentText,
                    CreatedOn = _dateTimeHelper.ConvertToUserTime(nc.CreatedOnUtc, DateTimeKind.Utc)

                };

                var customer = nc.Customer;
                string avatarUrl = "待修改";//_pictureService.GetPictureUrl(customer.GetAttribute<int>(SystemCustomerAttributeNames.AvatarPictureId), _mediaSettings.AvatarPictureSize, false);
                if (String.IsNullOrEmpty(avatarUrl) && _customerSettings.DefaultAvatarEnabled)
                    avatarUrl = _pictureService.GetDefaultPictureUrl(_mediaSettings.AvatarPictureSize, PictureType.Avatar);
                commentModel.CustomerAvatarUrl = avatarUrl;

                model.ShareBuyCommentModels.Add(commentModel);
            }
        }

        [NonAction]
        private void PrepareShareBuyPictureModels(ShareBuyModel model)
        {
            foreach (var shareBuyPictureModel in model.ShareBuyPictureModels)
            {
                shareBuyPictureModel.PictureUrl = _pictureService.GetPictureUrl(shareBuyPictureModel.PictureId,533);
                shareBuyPictureModel.PictureUrl90 = _pictureService.GetPictureUrl(shareBuyPictureModel.PictureId,90);
            }
        }
        private void PrepareShareBuyDefaultPictureModel(ShareBuyModel model)
        {
            var entity = _pictureService.GetPictureById(model.DefaultPictureId);
            model.DefaultPictureModel = new ShareBuyPictureModel
            {
                PictureId =entity!=null? entity.Id:0,
                DisplayOrder = 0,
                PictureUrl = _pictureService.GetDefaultPictureUrl(),
                ShareBuyId = model.Id,
                Default = true
            };
        }
        [NonAction]
        protected IList<CategoryNavigationModel.CategoryModel> PrepareCategoryNavigationModel( IList<Category> breadCrumbs)
        {
            var result = new List<CategoryNavigationModel.CategoryModel>();
            foreach (var category in breadCrumbs)
            {
                var categoryModel = new CategoryNavigationModel.CategoryModel()
                {
                    Id = category.Id,
                    Name = category.GetLocalized(x => x.Name),
                    SeName = category.GetSeName()
                };
                result.Add(categoryModel);
            }

            return result;
        }
        #endregion
    }
}
